Скролл-эффекты — это тренд, возникший в веб-дизайне несколько лет назад и все еще набирающий обороты. В этой статье я попытаюсь рассказать о популярных разновидностях таких эффектов, привести несколько примеров реального использования и поделиться шикарным инструментом для комфортной работы с ними.
Мы будем называть scroll-эффектами любые сценарии и приемы, реализуемые на веб-странице, так или иначе связанные с направлением и/или позицией прокрутки этой страницы относительно окна браузера.
К сожалению, пока не существует никаких отраслевых стандартов по поводу именования различных видов скролл-эффектов. Поэтому давайте рассмотрим самые популярные из них и дадим им собственные, наиболее подходящие по смыслу названия.
1. Parallax (Параллакс).
Эффект движения слоев страницы с разной скоростью при скролле. Обычно, в соответствии с оптическим представлением параллакса, слои, находящиеся ближе к наблюдателю, должны двигаться быстрее слоев, находящихся на удалении.
Для справки, вот определение из википедии: «Паралла́кс (греч. παραλλάξ, от παραλλαγή, «смена, чередование») — изменение видимого положения объекта относительно удалённого фона, в зависимости от положения наблюдателя.»
Например, в этом демо надпись Parallax — ScRolling in the Deep движется медленнеe скролла вниз и плавно исчезает, при этом задний фон верхней части страницы движется вверх немного быстрее скролла.
2. Back to top (Вернуться вверх).
Приятная и полезная кнопка «Back to top» изначально скрыта, появляется только тогда, когда страница немного проскроллена вниз. Вот демо.
3. Sticky (Прилипание)
Суть техники заключается в том, что элемент при скролле ведет себя как position: relative
относительно своего родителя, пока его верхняя граница не достигнет верхнего края окна (viewport-a). При дальнейшем скролле вниз элемент ведет себя как position: static
, будто отвязывается от родителя и «прилипает» к границе окна. Вот, к примеру, демо, в котором верхняя панель навигации реализована c эффектом «sticky».
Этой техникой также можно пользоваться для «прилепливания» элементов к нижней, левой или правой границе экрана, в зависимости от позиции и направления скролла.
Надо сказать, что СSS свойство position: sticky
(позволяет с легкостью реализовывать подобные эффекты без применения javascript) описано в черновике спецификации CSS Positioned Layout Module Level. Но вот с поддержкой браузерами пока совсем туго.
4. Reversed sticky (Реверсное прилипание).
Эффект, по сути, похож на предыдущий, но элемент прячется за границей окна при скролле вниз и появляется только при обратном скролле (вверх). Будет намного легче понять, о чем идет речь, немного поигравшись с демо.
5. Progress bar (Индикатор прокрутки).
Разновидности сценариев для визуализации текушего положения пользователя на странице при скролле. Например, в этом демо есть веселый индикатор прокрутки внизу страницы.
6. Accordion (Аккордеон).
Этот сценарий подразумевает последовательное применение stcicky-эффекта к заголовкам разделов страницы при скролле. А вот и демо
7. Menu Spy (Сопровождающее меню).
Этот сценарий хорошо известен под именем scroll spy в twitter bootstrap. Он подразумевает подсветку пунктов меню навигации, в зависимости от положения скролла, например, как в этом демо.
8. Staging (Сцена).
Самый сложный и эффектный сценарий, при котором некоторый блок, сопоставимый с размерами окна, фиксируется относительно видимой области страницы. В процессе прокрутки страницы сам блок остается неподвижным, однако, положение скролла влияет на развитие некого сценария внутри него. Это могут быть движения персонажей, появление или исчезновение контента, анимации и т.д. Смотрите демо.
Общие проблемы при реализации любых сценариев со скролл-эффектами.
Во-первых, при написании скролл-эффектов нужно учитывать большое количество факторов и величин:
- Размер всего документа.
- Размеры и позиции элементов, участвующих в сценарии, а также в некоторых случаях и их контейнеров.
- Размер и текущее положение видимой части документа (viewport) при скролле.
- Направление скролла.
- Адаптация при изменении размеров окна с отзывчивым (responsive) дизайном
Во-вторых, математические вычисления для описания сценариев получаются довольно массивными, а их сложность возрастает с ростом количества эффектов.
В-третьих, на мобильных девайсах все работает плохо и с тормозами. Javascript изначально работает медленнее. В добавок к этому, мобильные браузеры блокируют выполнение javascript во время скролла.
В-четвертых, Вы никогда не знаете, что искать в Гугле. В большинстве случаев не понятно, как называется тот или иной скролл-эффект. В этом случае, найти готовое решение довольно сложно.
Что такое Scroolly?
Scroolly — это jquery-плагин, который предоставляет Вам простой синтаксис для создания и конфигурирования скролл-эффектов. Он прост в освоении, довольно легковесный и позволяет создавать сколь угодно сложные сценарии. Нужно сказать, что все демо, которые были приведены выше, реализованы с помощью Scroolly!
Немаловажным фактом является то, что автор плагина не какой-то заморский дядька, а самый настоящий минский парень Борис Мосунов. Scrooly распространяется под свободной лицензией и находится здесь: github.com/chayka/jQuery.Scroolly
Правила, их границы и области действия.
Итак, в процессе скролла, в зависимости от положения прокрутки сраницы, нам нужно применять к элементам некоторые правила. Для этого необходимо определить границы действия этих правил.
Чтобы было проще понять о чем идет речь, приведу абстрактный пример:
- Нужно плавно показать и плавно скрыть некоторый элемент, когда при скролле он будет входить в область видимости и выходить из нее. Элемент должен начать появляться после того, как его верхняя кромка будет на 100px выше нижней границы видимой области окна и полностью появится, когда его нижняя кромка будет на 100px выше нижней границы видимой области окна. Та же логика с исчезновением, только в симметрично обратном порядке.
- Элемент нужно повернуть на 180° во время скролла, пока он будет находится в зоне ±30% от центра видимой зоны.
Чертовски сложно воспринимается на слух, не правда ли? Лучше посмотрим на демо.
Давайте договоримся, что мы будем называть видимую область документа словом «viewport». К сожалению, я не могу найти короткий русский аналог этого слова :)
В итоге, здесь мы можем выделить 3 области действия правил c 6-ю границами. Давайте опишем их:
- Точка, находящаяся на 100px ниже верхней границы элемента, совпадает с нижней границей viewport (элемент начинает появляться)
- Точка, находящаяся на 100px выше верхней границы элемента, совпадает с нижней границей viewport (элемент заканчивает появляться)
- Точка, находящаяся на 30% ниже центра viewport, совпадает с центром элемента (элемент начинает поворот)
- Точка, находящаяся на 30% выше центра viewport, совпадает с центром элемента (элемент заканчивает поворот)
- Точка, находящаяся на 100px ниже верхней границы элемента, совпадает с верхней границей viewport (элемент начинает исчезать)
- Точка, находящаяся на 100px выше верхней границы элемента, совпадает с верхней границей viewport (элемент заканчивает исчезать)
А теперь подумайте, с чего Вы начали бы описывать всю эту логику? Даже в таком простом сценарии с одним элементом в вычислениях участвуют размер документа, размер viewport, положение viewport, размер элемента, положение элемента, положение скролла… черт возьми, как же не запутаться?
Scroolly спешит на помощь.
Вся прелесть scroolly заключается в том, что каждая из этих границ областей действия правил задается с помощью вот такого наглядного синтаксиса:
el-top = vp-bottom - 100px
(элемент начинает появляться)el-bottom = vp-bottom - 100px
(элемент заканчивает появляться)el-center = vp-center + 30vp
(элемент начинает поворот)el-center = vp-center - 30vp
(элемент заканчивает поворот)el-top = vp-top + 100px
(элемент начинает исчезать)el-bottom = vp-top + 100px
(элемент заканчивает исчезать)
А весь сценарий описывается так:
$('.my-element').scroolly([
{
from: 'el-top = vp-bottom - 100px',
to: 'el-bottom = vp-bottom - 100px',
cssFrom:{opacity:'.0'},
cssTo:{opacity:'1'}
},
{
from: 'el-center = vp-center + 30vp',
to: 'el-center = vp-center - 30vp',
cssFrom:{'transform': 'rotate(0deg)'},
cssTo:{'transform': 'rotate(180deg)'}
},
{
from: 'el-top = vp-top + 100px',
to: 'el-bottom = vp-top + 100px',
cssFrom:{opacity:'1'},
cssTo:{opacity:'.0'}
}
]);
Где vp
— viewport, а el
— элемент. Также можно пользоваться абстракциями doc
для документа и con
для контейнера элемента. А теперь об этом подробнее и с картинками…
У каждого из них есть опорные точки, которые можно использовать в синтаксисе scroolly:
viewport: vp-top
, vp-center
, vp-bottom
элемент: el-top
, el-center
, el-bottom
контейнер: con-top
, con-center
, con-bottom
документ: doc-top
, doc-center
, doc-bottom
Вот несколько примеров описания областей действия правил c помощью синтаксиса scrolly:
Документация
Если Вас заитересовал плагин scroolly обязательно посмотрите официальную документацию. А она существует, и даже представлена в 2-х вариантах:
- Для ленивых и нетерпеливых — github.com/chayka/jQuery.Scroolly/wiki/Short-Story
- Для неторопливых и вдумчивых — github.com/chayka/jQuery.Scroolly/wiki/Long-Story
Ну и самое главное: обязательно посмотрите видео с нашей конференции 4front, на котором Борис сам захватывающе рассказал про скролл-эффекты в целом и scroolly в частности.
В заключение
Автор библиотеки открыт для отзывов, предложений и пулл-реквестов. Репортите баги, присоединяйтесь к разработке, а главное — пробуйте использовать scroll-эффекты как в реальных проектах, так и для баловства и саморазвития.
Добрый день. Отличный плагин! Можете добавить еще 2 функции: плавный скроллинг при прокрутке страниц и плавный скроллинг при клике по ссылке с якорем?
Мне кажется «Reversed sticky» немного не правильное название, я его называю «pursuing» (преследование) и даже выделил свою наработку в плагин
немного просветился на тему этих полезных рюшек. Всё таки с ними хорошо. Спасибо
Здравствуйте, Дмитрий.
Спасибо за материал.
С 34-ой секунды ролика пропадает звук у ведущего.
Есть возможность «починить» ?
привет, там моно звук с 34 сек
(только в одном из каналов :)
Отлично! Подскажите, с помощью вашего плагина можно реализовать плавающие блоки в пределах родительского контейнера?
Михаил, не очень понятен вопрос. Хотелось бы подробнее, в идеале ,если бы вы дали ссылку на какой-нибудь сайт, где подобное реализовано, чтобы понимать о чем речь. Вот мой skype: boris.mossounov. Свяжитесь со мной и я постараюсь помочь.
Извините за тупой вопрос. Разобрался
Привет, классный плагин) Подскажите, как можно изменить уже сформированные при загрузке страницы значения:
Вот, например, как я могу переписать значение «screen_modifier» при каком-либо событии (ресайзе в моём случае)? Пробовал заново вызывать функцию $(‘.to-fix’).scroolly(…) в обработчике ресайза, но безуспешно.
Дмитрий, не уверен, что до конца понял вопрос. Но я бы на вашем месте присмотрелся к относительным величинам, которые можно задавать в синтаксисе вроде 50con, 25el. Посмотрите полную документацию и демки на гитхабе здесь только пара базовых примеров. Если когда-нибудь руки дойдут, планировал сделать что-нибудь вроде 25(.some-selector). Но пока некогда.
Спасибо за ответ, Борис. Был на гитхабе, насколько я понял, здесь перевод Long Story, или нет? Немного поясню свой вопрос. При загрузке страницы задается:
Как я могу поменять это правило после загрузки страницы при каком-либо событии? Вот, например, на это:
Я пытаюсь просто заново вызвать эту функцию с новыми параметрами в обработчике ресайза, но в итоге скроллинг не работает ни по первому правилу, ни по последнему.
Борис, отличный плагин!
Не смог сам разобраться, подскажите, предусмотрено в нем сохранение ширины плавающего элемента?
Чтобы при инициализации плагин рассчитывал текущую ширину плавающего блока, и принудительно прописывал ее в атрибут style элемента.
Просто при размещении плавающего блока в левой колонке и использовании адаптивной верстки — этот блок разваливается при получении fixed, а задать ширину в css не получится.
По примеру, как это сделано здесь:
https://github.com/internet-design-studio/stickIt
, или здесь:
https://github.com/emn178/jquery-stickit
Как можно отключить какой-либо эффект, например, после того как один раз он уже отработал?
Всё круто! Есть вопрос: как вызвать обработчик scroolly без скроллинга?
Нужно для того, чтобы после обновления страницы, когда viewport автоматом перемещается на старую позицию, там всё корректно отображалось.
Полезная статейка. Эффект Parallax вообще зачет!
Привет. Большое спасибо за интересную статью!
С помощью scrooly можно реализовать такое — http://doitinbound.com/wp-content/uploads/2015/02/intercom-lp-parallax.gif очень интересный эффект.
Пример на сайте — https://www.intercom.io/customer-support
Если не затруднит, подскажите, какая тут логика событий? Спасибо
Здравствуйте! Отличный плагин спасибо большое! Ваш плагин довольно полно охватывает проблемы скролинга по вертикле, а как обстоят дела горизонтальным скролингом? Если ваш плагин не работает с горизонтальной прокруткой, может подскажете какое нибудь решение, которое можно поковырять! Спасибо!
Здравствуйте! Как-то некорректно работает Parallax если нужно перевести позицию фоновой картинки с положительного значения в отрицательное.
$(‘.parallax-section’).scroolly([
{
from: 'el-top = vp-bottom + 100px',
to: 'el-bottom = vp-top + 100px',
cssFrom:{'background-position':'50% 100px'},
cssTo:{'background-position':'50% -100px'}
},
]);
Если переводить с положительного в 0, или с 0 до отрицательного, то работает отлично. Но как сделать, что бы работал выше указанный код?
Привет!
Как воспроизвести скролл на следующую страничку при достижении посетителем конца текущей?
БЕЗ PHP AJAX — нужно JQUERY только
Спасибо
Alisa @ http://www.dogica.com
А как его подключить?